Skip to content

Add new Firmware TPM (fwTPM)#474

Open
dgarske wants to merge 12 commits intowolfSSL:masterfrom
dgarske:fwtpm
Open

Add new Firmware TPM (fwTPM)#474
dgarske wants to merge 12 commits intowolfSSL:masterfrom
dgarske:fwtpm

Conversation

@dgarske
Copy link
Copy Markdown
Contributor

@dgarske dgarske commented Mar 21, 2026

Summary

  • Add firmware TPM 2.0 server (fwTPM) implementing TPM 2.0 spec v1.38 (105/113 commands, 93% coverage)
  • Spec-compliant primary key derivation: deterministic RSA (iterative KDFa prime generation), ECC (KDFa scalar, Q=d*G), KEYEDHASH/SYMCIPHER keys — same seed + template always produces the same key
  • ChangePPS / ChangeEPS hierarchy commands with seed regeneration and cache flush
  • NV storage with TLV journal format (flash-friendly, append-only)
  • Socket (mssim) and TIS/SHM transports for desktop, UART transport for embedded
  • STM32 Cortex-M33 bare-metal port with TrustZone (CMSE) support
  • Shared crypto refactoring: extract KDFa/KDFe, AES-CFB, HMAC/Hash to tpm2_crypto.c
  • Bounds-checked TPM2_Packet_ParseU16Buf variant for safer response parsing
  • Auth validation: reject oversized auth values instead of silent truncation
  • SIGTERM/SIGINT signal handler for graceful NV save on server kill

fwTPM Server

Core TPM 2.0 command processing in src/fwtpm/:

  • fwtpm_command.c — 105 command handlers with full auth, sessions, parameter encryption
  • fwtpm_nv.c — TLV journal NV storage (file-based default, HAL-abstracted for flash)
  • fwtpm_io.c — Socket transport (mssim + swtpm protocol auto-detection)
  • fwtpm_tis.c / fwtpm_tis_shm.c — TIS register interface via POSIX shared memory
  • fwtpm_crypto.c — Key generation, sign/verify, seed encrypt/decrypt helpers
  • Clock HAL with NV-persisted clockOffset

Build: ./configure --enable-fwtpm && make

Example: wolfSSL/wolftpm-examples#1

Primary Key Derivation (TPM 2.0 Part 1 Section 26)

  • RSA: iterative KDFa prime generation with labels "RSA p" / "RSA q"
  • ECC: KDFa scalar derivation, public point Q = d*G
  • KEYEDHASH/SYMCIPHER: KDFa with algorithm-specific labels
  • hashUnique = H(sensitiveCreate.data || unique) per Section 26.1
  • Primary cache retained as performance optimization, no longer required for correctness

UART Transport (--enable-swtpm=uart)

New transport option for wolfTPM client library to communicate with embedded fwTPM over serial:

  • ./configure --enable-swtpm=uart — uses termios serial I/O instead of TCP sockets
  • TPM2_SWTPM_HOST env var selects serial device at runtime
  • Same mssim protocol as socket transport (compatible with all wolfTPM examples)

Testing

  • 311 tpm2-tools compatibility tests (scripts/tpm2_tools_test.sh)
  • Full wolfTPM example suite (examples/run_examples.sh)
  • libFuzzer harness with corpus generator (tests/fuzz/)
  • m33mu Cortex-M33 emulator CI test (scripts/fwtpm_emu_test.sh)
  • ASan / UBSan clean
  • 20 CI matrix configurations (pedantic gcc/clang -Werror, sanitizers, feature-disable variants)

wolfSSL-Fenrir-bot

This comment was marked as resolved.

@dgarske dgarske force-pushed the fwtpm branch 3 times, most recently from 9c0208f to eae465e Compare March 21, 2026 23:51
@dgarske dgarske changed the title Add fwTPM firmware TPM 2.0 server with STM32 port Add fwTPM firmware TPM 2.0 server Mar 21, 2026
@dgarske dgarske changed the title Add fwTPM firmware TPM 2.0 server Add new Firmware TPM (fwTPM) Mar 22, 2026
@dgarske dgarske force-pushed the fwtpm branch 2 times, most recently from b186ecc to f529484 Compare March 23, 2026 21:28
@dgarske dgarske assigned wolfSSL-Bot and unassigned dgarske and aidangarske Mar 24, 2026
wolfSSL-Fenrir-bot

This comment was marked as resolved.

…_examples.sh and

  tpm2_tools_test.sh to make test for fwtpm as well
wolfSSL-Fenrir-bot

This comment was marked as resolved.

This comment was marked as resolved.

@aidangarske aidangarske requested a review from danielinux March 25, 2026 20:51
Comment on lines +339 to +342
pkt.pos = 2; /* skip size we already read */
TPM2_Packet_ParsePublic(&pkt, &pub2b);
XMEMCPY(pub, &pub2b.publicArea, sizeof(TPMT_PUBLIC));
*pos += pubSz;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This calls TPM2_Packet_ParsePublic which parses the size again. I think restoring might corrupt saved records. Please verify with a test

/* Check if journal has space */
if (ctx->nvWritePos + entrySize > hal->maxSize) {
/* Compact and retry */
rc = FWTPM_NV_Save(ctx);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cyclic recursion seems possible between FWTPM_NV_Save and FwNvAppendEntry if compacting is not sufficient the functions will keep calling each other

FwFlushAllSessions(ctx);
}

FWTPM_NV_Save(ctx);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return value is discarded here, this functions will return success regardless of FWTPM_NV_Save result. Review error handling in this function.

Copilot AI review requested due to automatic review settings April 3, 2026 17:42

This comment was marked as resolved.

This comment was marked as resolved.

wolfSSL-Fenrir-bot

This comment was marked as resolved.

- Fixed LE/BE endianness mismatch in FwNvMarshalPublic/FwNvUnmarshalPublic
- Added nvCompacting guard to prevent infinite recursion between FwNvAppendEntry and FWTPM_NV_Save
- Check FWTPM_NV_Save return value in FwCmd_Shutdown and other callers
- Reinitialize hash context per iteration in TPM2_KDFe_ex for multi-block derivation
- Align packet->pos to inSensSize boundary in ParseSensitiveCreate
- Clean up wolfCrypt resources if FWTPM_NV_Init fails in FWTPM_Init
- Reset g_initialized on fuzzer reinit failure
- Fix configure.ac so --enable-swtpm=uart doesn't force TIS mode
- Update README command count from 103/91% to 105/93%
@aidangarske aidangarske removed their request for review April 3, 2026 18:55
@aidangarske aidangarske self-assigned this Apr 3, 2026
@aidangarske aidangarske requested a review from danielinux April 3, 2026 19:21
@dgarske dgarske assigned danielinux and wolfSSL-Bot and unassigned aidangarske and dgarske Apr 5, 2026
- Fixed memory leak in FwComputeRpHash — initialized rc = 0, added FWTPM_FREE_VAR(hashCtx) before both early returns to prevent heap leak under
  WOLFTPM_SMALL_STACK
- Removed static from eccUniqueBuf in FwCmd_CreatePrimary — eliminates thread-safety risk and stale data persistence across calls (132-byte buffer is
  fine on stack)
- Initialized rc = TPM_RC_SUCCESS in FWTPM_ProcessCommand — prevents use of uninitialized variable
- Added XMEMSET(cmdAuths, 0, sizeof(cmdAuths)) in FWTPM_ProcessCommand — zeroes auth struct array to prevent use of garbage data on partial parse
- Added auth-parse error check — if auth area parsing fails (e.g. TPM_RC_AUTHSIZE), returns error response instead of falling through to command dispatch
- Moved pwSz/avSz into inner scope — declared where actually used instead of function scope
- Added TPM2_ForceZero(&bindAuth, ...) in FwCmd_StartAuthSession — zeroizes hierarchy auth secrets before scope exit
- Fixed NV handle mask consistency — changed == NV_INDEX_FIRST to == (NV_INDEX_FIRST & 0xFF000000) to match style elsewhere
- Added wc_HmacInit() in FwWrapPrivate — call wc_HmacInit before wc_HmacSetKey, matching pattern used in FwComputeSessionHmac and FwDeriveWrapKey
- Added wc_HmacInit() in FwUnwrapPrivate — same fix for the unwrap path
- Fixed UART (void)port suppression — removed erroneous cast that hid the fact port is used later
- Added NULL check before atoi(port) — prevents undefined behavior if port is NULL
- Restored idx >= inputSz bounds check in TPM2_ASN_DecodeX509Cert — defense-in-depth against OOB read on malformed certificates
- Restored *sigSz < 3 minimum in TPM2_ASN_RsaUnpadPkcsv15 — valid PKCS#1 v1.5 needs at least 0x00|0x01|0xFF
- Fixed summary alignment — consistent column spacing for fwTPM output lines
@aidangarske aidangarske requested review from Copilot and removed request for Copilot April 6, 2026 19:13
Copilot AI review requested due to automatic review settings April 6, 2026 22:12

This comment was marked as resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants